package org.tsisa.smsplugin;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;


import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;

public class ReadSms extends CordovaPlugin{
	public static final String READ = "read";
	private CallbackContext cbContext;
	public static final JSONObject result = new JSONObject();
	public static final ArrayList<String> phoneNumbers = new ArrayList<String>();
	public static final HashMap hm = new HashMap();
	public static final ArrayList<String> conversationAddresses = new ArrayList<String>();
	public static final ArrayList<Conversation> conversations = new ArrayList<Conversation>();
	public static int rangeFrom=0;
	public static int rangeTo=1000;
	public static String rangeSort = "asc"; // asc by default
	public static String rangeFromDate = "";
		
	@Override
	public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
		this.cbContext = callbackContext;
		JSONObject range = args.optJSONObject(0).optJSONObject("range");
		Log.i("SmsRead","range : " + range + " range : " + args);
		if(range!=null){
			int isRangeFrom = range.optInt("from");
			int isRangeTo = range.optInt("to");
			String isRangeSort = range.optString("sort");
			rangeFromDate = range.optString("fromDate");
			Log.e("SmsRead","fromDate : " + rangeFromDate);
			if(isRangeFrom != 0){
				rangeFrom = isRangeFrom;
			}
			if(isRangeTo!=0){
				rangeTo = isRangeTo;
			}
			if(!isRangeSort.equals("")){
				rangeSort = isRangeSort;
			}
		}
		String addressesObject = args.getJSONObject(0).get("address").toString();
		Log.i("SmsRead","addressesObject : " + addressesObject);
		String[] phoneAddresses = addressesObject.split(",");
		if(!addressesObject.equals("null")){
			for(int i = 0; i<phoneAddresses.length; i++){
				phoneNumbers.add(phoneAddresses[i]);
				 Log.i("SmsRead","Address : '" + phoneAddresses[i]+"'");
			}
		}
		else{
			Log.i("SmsRead","No address was given");
		}
		if (action.equals(READ)) {
			return getSms();  
		}
		else {    
			this.cbContext.error("Invalid Action");Log.e("SmsRead","Error CB");
			return false;
	    }
	}
	
	public boolean getSms() throws JSONException{
		getSmsTexts("inbox");
		getSmsTexts("sent");
		JSONArray deviceConversations = new JSONArray();
		deviceConversations = sortConversations(rangeSort);
		
        this.cbContext.success(deviceConversations);
        Log.i("SmsRead", "" + deviceConversations);
		return true;
	}
	
	public void getSmsTexts(String source) throws JSONException{
		Uri uri = Uri.parse("content://sms/"+source);
		ContentResolver contentResolver = cordova.getActivity().getContentResolver();
		Cursor c = contentResolver.query(uri, null, null, null, null);
		long startTime = System.currentTimeMillis();
		int smsCounter = 0;
		
        while (c.moveToNext()) {
            JSONObject current = new JSONObject();
            smsCounter++;
            String address = c.getString(c.getColumnIndex("address"));
            String date = c.getString(c.getColumnIndex("date"));
           
			if((phoneNumbers.isEmpty() || addressIsContained(address)) && (date.compareTo(rangeFromDate)>=0)){
				String message = c.getString(c.getColumnIndex("body"));
				 Log.w("SmsRead","date : " + date);
				String user = "";
				if(source.equals("inbox")){
					user ="false";
			    }
			    else{
			    	user ="true";
			    }
				ConversationCell text = new ConversationCell(message, date, user);
				Conversation spesificConversation;
				boolean convAddressFound = false;
				for(int i=0;i<conversationAddresses.size(); i++){
					if(conversationAddresses.get(i).toString().contains(address)){
						convAddressFound = true;
						updateConversations(conversationAddresses.get(i).toString(),text);
					}
				}
				if(!convAddressFound){
					conversationAddresses.add(address);
					Conversation conv = new Conversation(address);
					conv.updateConversation(text);
					conversations.add(conv);
				}
			}           
        }
		long endTime = System.currentTimeMillis();
        Log.i("SmsRead",source + ", count: " + smsCounter+ ", time taken: " +(endTime - startTime));		
	}
	
	public void updateConversations(String address, ConversationCell message){
		for(int i=0; i<conversations.size(); i++){
			if(address.contains(conversations.get(i).getAddress())){
				conversations.get(i).updateConversation(message);
			}
		}
	}
	
	public boolean addressIsContained(String address){
		Iterator<String> it = phoneNumbers.iterator();
		while(it.hasNext()){
			String number = it.next();
			if(address.contains(number)){
				return true;
			}
		}
		return false;
	}
	
	public JSONArray sortConversations(String range) throws JSONException{
		JSONArray deviceConversations = new JSONArray();
		Log.e("SmsRead","conversations size" + conversations.size());
		for(int i=0; i<conversations.size(); i++){
			conversations.get(i).sortConversation(range);
			JSONObject conversationsInfo = new JSONObject();
			conversationsInfo.put("address", conversations.get(i).getAddress());
			conversationsInfo.put("messages",  conversations.get(i).parseMessagesToJSONArray(rangeFrom,rangeTo));	
			deviceConversations.put(conversationsInfo);
		}
		return deviceConversations;
	}
}
